1. Field of Invention
The present invention relates in general to the data processing field. More particularly, the present invention relates to the field of addressing schemes in computer systems.
2. Background Art
Since the dawn of the computer age, computer systems have evolved into extremely sophisticated devices that may be found in many different settings. Computer systems typically include a combination of hardware (e.g., semiconductors, circuit boards, etc.) and software (e.g., computer programs). As advances in semiconductor processing and computer architecture push the performance of the computer hardware higher, more sophisticated computer software has evolved to take advantage of the higher performance of the hardware, resulting in computer systems today that are much more powerful than just a few years ago.
Computer systems have addressing capabilities that are defined by the computer hardware. The address space of a computer system is the range of addresses available to reference data, instructions, etc., and is determined by the size (in bits) of the address. The address size is one of the fundamental architectural features of a computer system. Early computer systems were single-user computers that could handle only a single task at a time, mapping all data into a single address space, and swapping data into and out of the address space whenever a new task needed to be performed. Later, computers were developed that supported multiple users and processes. A computer system that supports multiple processes must manage the allocation of the address space among the processes. In general, each process has its own working data that is unique to that process. This is true both for uni-processor and multi-processor computer systems.
Computer architectures generally support “process local addressing”, wherein storage accesses are resolved only in the context of the executing process. The processor uses process-unique segment tables (which are also referred to in the art as “translation tables”) to translate a process local address to a virtual address. Two different processes may reference storage using the same process local address, but because the operating system kernel populates the segment tables with separate virtual address ranges for each process, different virtual addresses are referenced, which then results in accesses to different storage. Process local addressing is commonly used in the industry. The process local addressing mechanism is used to prevent one process from accessing the storage of another process, either by accident or intentionally. Hence it is desirable for the operating system kernel to arrange the working data of each process to reside in process local storage, which is referenced with process local addresses.
However, there are situations where cooperating processes need to share at least a portion of their working storage. Consequently, the operating system kernel typically provides one or more sharing mechanisms whereby cooperating processes share at least a portion of their working storage. Two such sharing mechanisms are respectively referred to as “shared memory” and “memory mapped files”. The first sharing mechanism, i.e., shared memory, is a technique whereby the operating system kernel populates a portion of each cooperating process' segment table with the same virtual address ranges, and provides backing storage to support those virtual addresses. Thus the cooperating processes can reference the same storage. Furthermore, if the operating system kernel associates the same process local addresses with the same virtual addresses in each process' segment table, then the cooperating processes can reference the same storage using the same process local addresses.
The second sharing mechanism, i.e., memory mapped files, is a similar technique, but in this case, the backing storage is provided by a file existing somewhere in the file system. The cooperating processes reference the same storage, which is part of the file.
These sharing mechanisms are useful, but require some cooperation between the processes. In this regard, it should be noted that a process' working data is not located in one of the shared areas. A process must explicitly create the shared memory object or map the file, and then must define the portions of its working storage that it wants to share, based on the resultant address of the shared area. Also, the processes must cooperate in addressing the shared storage. If any of the shared storage contains addresses of other portions of the shared storage, then all processes either must be able to reference the shared storage using the same process local addresses, or must be able to apply an offset to the address when referencing the shared storage. In addition, the same care must be taken when storing an address in the shared storage.
In some situations, these sharing mechanisms are difficult or impossible to implement. Often processes must share data which cannot be organized as required for one of the sharing mechanisms. As an example, consider a server process which performs a given server function for a client process. The server function may involve extracting large quantities of data from, or storing large quantities of data into, the storage of the client process. Complexity is introduced by the fact that the client process' storage could be anywhere. For example, it may be in its own working storage or in the working storage of a procedure which called it; it may be in the storage associated with a shared memory object or memory mapped file; it may be in a heap or static storage; or it may be in some combination of these locations. The client process's storage may require traversing complex structures involving several levels of indirection and pointer dereferencing to locate all of the storage to be accessed.
Various techniques for dealing with these complexities are possible, but each undesirably impacts performance. In one such technique, shared memory is used as an intermediate buffer. The server process extracts data from, or puts data into, this intermediate storage and the client process copies data from its own working storage into the shared area before calling a server function, or copies data from the shared area into its own working storage after calling the server function. The overhead associated with the intermediate copy is undesirable, both in terms of setting up the intermediate storage, as well as the duplicated copy, particularly if large quantities of data are involved.
In another technique for dealing with these complexities, an operating system kernel function is used by the server process to “get from” or “put into” the local storage of the client process. Depending on how it is implemented, this may also involve an intermediate copy of data. Regardless, this type of function is very general-purpose in nature, e.g., get/put a specific number (n) of bytes starting at a specified address, and does not possess the know-how to traverse the client data structures. As a result, the server process needs to invoke this function for every leg of the traversal, and again the impact on performance is undesirable.
A need exists for an enhanced mechanism for accessing the process local storage of another process in a controlled manner.